<?php
/**
 *	FILENAME: 		/libraries/webct.php
 *	DESCRIPTION:	This library that uses the PHP Snoopy library to interact with Villanova's WebCT system.
 *	AUTHOR:			Casey Burkhardt
 *	VERSION:		1.0.0
 *	LAST MODIFIED:	12/30/2009
 **/

/**
 THIS SCRIPT IS UNSTABLE AND SITLL UNDER DEVELOPMENT.
 ITS USE IS EXPERIMENTAL AND SHOULD NOT BE USED IN PRODUCTION AT THIS TIME.
 **/
die();

require_once($_SERVER['DOCUMENT_ROOT'] . "/config/environment.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/libraries/Snoopy.class.php");

function parseCookie($val) {
    $equalsSign = strpos($val, "=");
    $cookieName = substr($val, strlen("Set-Cookie: "), $equalsSign - strlen("Set-Cookie: "));
    $semiColon = strpos($val, ";");
    $cookieValue = substr($val, $equalsSign + 1, $semiColon - $equalsSign - 1);
    $result[$cookieName] = $cookieValue;
    return $result;
}

/**
 *	DESCRIPTION:	Returns a webCT authentication token.
 **/
function getWebCTAuthenticationToken($userName, $password) {
    // Create a new instance of Snoopy, the page fetching / parsing engine.
    $mainPage = new Snoopy;
    // Set a timeout, in case this thing doesn't work
    $mainPage -> read_timeout = 2;
    // We will need to fetch pages using HTTPS, so we must point Snoopy to our instance of curl.
    // This information is stored in our environment configuration.
    $mainPage -> curl_path = getCurlPath();
    // Set up appropriate Header Types, We'll reuse these...
    $rawHeaders["Accept"] = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
    $rawHeaders["Accept-Language"] = "en-us,en;q=0.5";
    $rawHeaders["Accept-Encoding"] = "gzip,deflate";
    $rawHeaders["Accept-Charset"] = "ISO-8859-1,utf-8;q=0.7,*;q=0.7";
    $rawHeaders["Keep-Alive"] = "300";
    $rawHeaders["Connection"] = "keep-alive";
    $mainPage -> rawheaders = $rawHeaders;

    // We need to get an initial session cookies from WebCT... I can tell this is going to be a pain already.
    // Let's just request the main page.
    echo "<br /> Requesting WebCT Main Page: <br />";

    if ($mainPage -> fetch("https://elearning.villanova.edu")) {
        while(list($key,$val) = each($mainPage->headers)) {
            if(strpos($val, "Set-Cookie: ") !== FALSE) {
                // If the header contains a cookie, set that cookie
                $mainPage -> cookies = array_merge(parseCookie($val), $mainPage -> cookies);
            }
            echo $key.": ".$val."<br>\n";
        }
        echo "<p>\n";
        echo "<PRE>".htmlspecialchars($mainPage->results)."</PRE>\n";
    } else {
        echo "error fetching document: ".$mainPage->error."\n";
        die();
    }
    $cookiesSoFar = $mainPage -> cookies;

    echo "<br /><br />Cookies: <br />";
    print_r($cookiesSoFar);
    echo "<br /><br />";

    // Now we need to fetch the WebCT Insertion Page
    $insertionPage = new Snoopy;
    $insertionPage -> read_timeout = 2;
    $insertionPage -> curl_path = getCurlPath();
    $insertionPage -> cookies = $cookiesSoFar;
    $insertionPage -> rawheaders = $rawHeaders;

    echo "<br />Requesting the WebCT Insertion Page: <br />";
    if ($insertionPage -> fetch("https://elearning.villanova.edu/webct/entryPageIns.dowebct")) {
        while(list($key,$val) = each($insertionPage->headers)) {
            if(strpos($val, "Set-Cookie: ") !== FALSE) {
                // If the header contains a cookie, set that cookie
                $insertionPage -> cookies = array_merge(parseCookie($val), $insertionPage -> cookies);
            }
            echo $key.": ".$val."<br>\n";
        }
        echo "<p>\n";
        echo "<PRE>".htmlspecialchars($insertionPage->results)."</PRE>\n";
    } else {
        echo "error fetching document: ".$insertionPage->error."\n";
        die();
    }
    $cookiesSoFar = $insertionPage -> cookies;

    echo "<br /><br />Cookies: <br />";
    print_r($cookiesSoFar);
    echo "<br /><br />";

    // Now we're going to hit up the WebCT Login Form.
    // But, we actually do this with a POST Request...
    // WebCT people are retards who don't understand HTTP standards...
    $postVars["insId"] = "102089011";
    $postVars["glcid"] = "URN%3AX-WEBCT-VISTA-V1%3A1468da52-9968-0617-0113-9c275d9d136f";
    $postVars["newUserGlcid"] = "URN%3AX-WEBCT-VISTA-V1%3A1468da52-9968-0617-0113-9c275d9d136f";
    $postVars["insName"] = "Villanova University";
    $postVars["actionType"] = "";

    $loginPage = new Snoopy;
    $loginPage -> read_timeout = 2;
    $loginPage -> curl_path = getCurlPath();
    $loginPage -> cookies = $cookiesSoFar;
    $loginPage -> rawheaders = $rawHeaders;

    echo "<br />Requesting the WebCT Logon Page: <br />";
    if ($loginPage -> submit("https://elearning.villanova.edu/webct/logonDisplay.dowebct", $postVars)) {
        while(list($key,$val) = each($loginPage->headers)) {
            if(strpos($val, "Set-Cookie: ") !== FALSE) {
                // If the header contains a cookie, set that cookie
                $loginPage -> cookies = array_merge(parseCookie($val), $loginPage -> cookies);
            }
            echo $key.": ".$val."<br>\n";
        }
        echo "<p>\n";
        echo "<PRE>".htmlspecialchars($loginPage->results)."</PRE>\n";
    } else {
        echo "error fetching document: ".$loginPage->error."\n";
        die();
    }
    $cookiesSoFar = $loginPage -> cookies;


    echo "<br /><br />Cookies: <br />";
    print_r($cookiesSoFar);
    echo "<br /><br />";


    // Let's set some WebCT Login Variables... FML
    $submitVars["insId"] = "102089011";
    $submitVars["glcid"] = "URN:X-WEBCT-VISTA-V1:1468da52-9968-0617-0113-9c275d9d136f";
    $submitVars["newUserGlcid"] = "URN:X-WEBCT-VISTA-V1:1468da52-9968-0617-0113-9c275d9d136f";
    $submitVars["insName"] = "Villanova University";
    $submitVars["gotoid"] = "";
    $submitVars["actionType"] = "";
    $submitVars["webctid"] = $userName;
    $submitVars["timeZoneOffset"] = "5";
    $submitVars["password"] = $password;
    $submitVars[""] = "OK";

    // Submit the Login Form
    $loginSubmission = new Snoopy;
    $loginSubmission -> read_timeout = 2;
    $loginSubmission -> curl_path = getCurlPath();
    $loginSubmission -> cookies = $cookiesSoFar;
    $loginSubmission -> rawheaders = $rawHeaders;

    echo "<br />Submitting the WebCT Logon Page: <br />";
    if ($loginSubmission -> submit("https://elearning.villanova.edu/webct/urw/lc102089011.tp0/authenticateUser.dowebct", $submitVars)) {
        while(list($key,$val) = each($loginSubmission->headers)) {
            if(strpos($val, "Set-Cookie: ") !== FALSE) {
                // If the header contains a cookie, set that cookie
                $loginSubmission -> cookies = array_merge(parseCookie($val), $loginSubmission -> cookies);
            }
            echo $key.": ".$val."<br>\n";
        }
        echo "<p>\n";
        echo "<PRE>".htmlspecialchars($loginSubmission->results)."</PRE>\n";
    } else {
        echo "error fetching document: ".$loginSubmission->error."\n";
        die();
    }
    $cookiesSoFar = $loginSubmission -> cookies;

    echo "<br /><br />Cookies: <br />";
    print_r($cookiesSoFar);
    echo "<br /><br />";

    // From the HTTP 302 request that was received, the resulting URL must now be parsed, so we can determine the next request location.
    $startIndex = strpos($loginSubmission -> results, "https://");
    $endIndex = strpos($loginSubmission -> results, '"', $startIndex);
    $url = substr($loginSubmission -> results, $startIndex, $endIndex - $startIndex);

    // The response to our request contained in invalid URL.  Figures, those WebCT folks at Blackboard are real geniuses...
    // The :80 port designator is redundant as https:// protocol is provided.
    // We'll strip this and use port 443 instead.
    $url = str_replace(":80", "", $url);

    // We're about to make another request... Let's move the output up a bit.
    echo "<br /><br /><br />ASSHOLE REQUEST:<br /><br /><br />\n";

    // Some debugging...
    echo "Requesting: ". $url . "<br />With Cookies: ";
    print_r($cookiesSoFar);
    echo "<br /><br />";

    $authenticatedPage = new Snoopy;
    $authenticatedPage -> read_timeout = 2;
    $authenticatedPage -> curl_path = getCurlPath();
    $authenticatedPage -> cookies = $cookiesSoFar;
    $authenticatedPage -> rawheaders = $rawHeaders;

    if ($authenticatedPage -> fetch($url)) {
        while(list($key,$val) = each($authenticatedPage->headers)) {
            if(strpos($val, "Set-Cookie: ") !== FALSE) {
                // If the header contains a cookie, set that cookie
                $authenticatedPage -> cookies = array_merge(parseCookie($val), $authenticatedPage -> cookies);
            }
            echo $key.": ".$val."<br>\n";
        }
        echo "<p>\n";
        echo "<PRE>".htmlspecialchars($authenticatedPage->results)."</PRE>\n";
    } else {
        echo "error fetching document: ".$authenticatedPage->error."\n";
        die();
    }
    $cookiesSoFar = $authenticatedPage -> cookies;

    echo "<br /><br />Cookies: <br />";
    print_r($cookiesSoFar);
    echo "<br /><br />";
}
?>